package org.shiro.auth.client.filter;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;

public abstract class Rpcable<T> {

  @SuppressWarnings({ "unchecked", "rawtypes" })
  protected List<T> call(String url) throws ClientProtocolException, IOException {
    HttpGet httpGet = getHttpGet(url);
    CloseableHttpClient httpClient = HttpClients.createDefault();
    CloseableHttpResponse rep = httpClient.execute(httpGet);
    HttpEntity resEntity = rep.getEntity();
    if (resEntity != null) {
      String jsonstr = EntityUtils.toString(resEntity, "utf-8");
      RpcResponse r = JSONObject.parseObject(jsonstr, RpcResponse.class);
      if (r.getFlag()) {
        Object data = r.getData();
        Type type = getClass().getGenericSuperclass();
        Type trueType = ((ParameterizedType) type).getActualTypeArguments()[0];
        Class c = (Class<T>) trueType;
        try {
          if (((Class) c.getField("TYPE").get(null)).isPrimitive()) {
            List<Object> rs = new ArrayList<>();
            rs.add(data);
            return (List<T>) rs;
          }
        } catch (IllegalArgumentException e) {
          e.printStackTrace();
        } catch (IllegalAccessException e) {
          e.printStackTrace();
        } catch (NoSuchFieldException e) {
          e.printStackTrace();
        } catch (SecurityException e) {
          e.printStackTrace();
        }
        String dataStr = JSONObject.toJSONString(data);
        return (List<T>) JSONObject.parseArray(dataStr, (Class<T>) trueType);
      } else {
        throw new RuntimeException(r.getMessage());
      }
    }
    return null;
  }

  HttpGet getHttpGet(String url) {
    HttpGet httpGet = new HttpGet(url);
    return httpGet;
  }

}
